import codecs
import re
import warnings

from bs4 import BeautifulSoup


""""负责解析xml"""


def init_sql_dom_tree(mapper_list, encoding='utf8'):
    sql_dict = {}
    """构建sql_dict"""
    for mapper in mapper_list:
        key = None
        #
        try:
            f = codecs.open(mapper, encoding=encoding)
            sql_doc = BeautifulSoup(f, 'xml')
            key = sql_doc.find('mapper').attrs['namespace']
            sql_list = sql_doc.find_all('sql')
            value = {}
            for sql in sql_list:
                sql_id = sql.attrs['id']
                value[sql_id] = sql
            sql_dict[key] = value
            template_list = sql_doc.find_all('template')
            templates = {}
            for template in template_list:
                template_id = template.attrs['id']
                templates[template_id] = template
            sql_dict['template'] = templates
        except FileNotFoundError:
            warnings.warn('File Not Found Error:', mapper)
        except KeyError:
            warnings.warn('XML Parse Error:', mapper)
            if key:
                del sql_dict[key]
        else:
            f.close()
    # print(sql_dict)
    return sql_dict


def replace(sql, params):
    temp = sql
    values = re.findall(r'[#$%]{.*?}', temp)
    for item in values:
        param = item[2: -1]
        if param in params:
            if item.startswith('#'):
                temp = temp.replace(item, "'" + params[param] + "'")
            if item.startswith('$'):
                temp = temp.replace(item, str(params[param]))
            if item.startswith('%'):
                pass
        else:
            raise KeyError("Key Not Found:" + item, sql)
    return temp


def createSQL(sql_ele, params):
    sql_str = __batisSQL(sql_ele)
    new_sql = replace(sql_str, params)
    return new_sql


def __batisSQL(sql_ele):
    if sql_ele.find_all('if'):
        pass
    if sql_ele.find_all('foreach'):
        pass
    sql_temp = sql_ele.text.strip()
    return sql_temp


class PyMybatisXMLError(TypeError):
    pass
